package com.hk.aefz.shiro.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.hk.aefz.shiro.Md5;
import com.hk.aefz.shiro.UserRealm;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.SubjectContext;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    //    ShiroFliterFactoryBean 3
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(
            @Qualifier("securityManager") DefaultWebSecurityManager securityManager
    ) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
//        设置安全管理器
        factoryBean.setSecurityManager(securityManager);
//        添加Shiro内置过滤器
        //        设置登录拦截
        Map<String, String> filterMap = new LinkedHashMap<>();
//        匿名访问
        filterMap.put("/navigation/index","anon");
        filterMap.put("/navigation/blogdetails","anon");
        filterMap.put("/navigation/login","anon");
        filterMap.put("/navigation/register","anon");
//        需要角色
        filterMap.put("/navigation/personblog","authc,roles[blogger]"); //个人博客
        filterMap.put("/essay/writing-blog","authc,roles[blogger]"); //写博客
        filterMap.put("/essay/admin-essay","authc,roles[blogger]"); //文章管理
        filterMap.put("/special/classify-admin","authc,roles[blogger]"); // 分类管理
        filterMap.put("/comment/pl-admin","authc,roles[blogger]"); // 评论管理
        filterMap.put("/navigation/**","anon");
        factoryBean.setFilterChainDefinitionMap(filterMap);
//        拦截后返回登录页面
        factoryBean.setLoginUrl("/navigation/login");
//        跳转到未经授权页面
        factoryBean.setUnauthorizedUrl("/error.html");
        return factoryBean;
    }

    //  DefaultWebSecurityManager 2 安全管理器
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(
            @Qualifier("userRealm") UserRealm userRealm,
            @Qualifier("cookieRememberMe") CookieRememberMeManager cookieRememberMe
    ) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//        关联UserRealm
        securityManager.setRealm(userRealm);
//        设置记住我有效期
        securityManager.setRememberMeManager(cookieRememberMe);
        return securityManager;
    }

//    记住我有效期
    @Bean(name = "cookieRememberMe")
    public CookieRememberMeManager cookieRememberMeManager() {
        CookieRememberMeManager cookieRememberMe = new CookieRememberMeManager();
        cookieRememberMe.getCookie().setMaxAge(60*60*24 ); //秒 有效期一小时
        return cookieRememberMe;
    }

    //    创建UserRealm类 需要自定义 1
    @Bean
    public UserRealm  userRealm(@Qualifier("hashedCredentialsMatcher") HashedCredentialsMatcher hashedCredentialsMatcher) {
        UserRealm userRealm = new UserRealm();
        userRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        return userRealm;
    }

//    Hash密码加密
    @Bean(name = "hashedCredentialsMatcher")
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("MD5"); //MD5加密算法
        hashedCredentialsMatcher.setHashIterations(new Md5().getHashIterations()); //指定加密的次数 ，次数越高越安全
        //此处的设置，true加密用的hex编码，false用的base64编码
        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
        return hashedCredentialsMatcher;
    }


    //    Shiro 整合 Thymeleaf
    @Bean
    public ShiroDialect getShiroDialect() {
        return new ShiroDialect();
    }

    /**
     * RestTemplate
     * 用于远程服务调用
     */
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }



}
